package com.yndsoft.jc.ui.memberpage;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;

import com.yndsoft.jc.model.Member;
import com.yndsoft.jc.model.SupplierAdmin;
import com.yndsoft.jc.netutils.AppUtils;
import com.yndsoft.jc.supplier.utils.ACache;
import com.yndsoft.jc.utils.ConstantValues;
import com.yndsoft.jc.utils.LogUtils;
import com.yndsoft.jc.utils.Pair;
import com.yndsoft.jc.utils.STIDUtil;
import com.yndsoft.jc.utils.SaveFileData;
import com.yndsoft.jc.utils.SecurityUtil;
import com.yndsoft.jc.utils.SharedPreferencesUtil;
import com.yndsoft.jc.utils.binary.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * Created by Cool on 2017/12/28.
 */

public class Session {

    SaveFileData mPreference;

    public String getChannelName() {
        return channelName;
    }

    public void setChannelName(String channelName) {
        this.channelName = channelName;
    }

    /**
     * Application 上下文
     */

    private Context mContext;

    /**
     * The version of OS
     */
    private int osVersion;

    /**
     * The user-visible version string. E.g., "1.0"
     */
    private String buildVersion;

    /**
     * The mobile model such as "Nexus One" Attention: some model type may have
     * illegal characters
     */
    private String model;

    public String getImei() {
        return mPreference.loadStringKey(P_IEIM, "");
    }

    private void setImei(String imei) {
        this.imei = imei;
        writePreference(new Pair<String, Object>(P_IEIM, this.imei));
    }

    /**
     * default constructor
     *
     * @param context
     */
    private Session(Context context) {

        mContext = context;
        mPreference = new SaveFileData(context, "app");
        osVersion = Build.VERSION.SDK_INT;
        buildVersion = Build.VERSION.RELEASE;
        try {
            model = android.os.Build.MODEL;
            AppUtils.clearExpiredFile(context, false);
            AppUtils.clearExpiredCacheFile(context);
            readSettings();
        } catch (Exception e) {
            LogUtils.e(e.getMessage());
        }


    }

    private String ulat;
    private String ulng;
    private String guid;

    public String getGuid() {
        guid = mPreference.loadStringKey(P_GUID, "");
        return guid;
    }

    public void setGuid(String guid) {
        this.guid = guid;
        writePreference(new Pair<String, Object>(P_GUID, this.guid));
    }

    public String getUlat() {
        ulat = mPreference.loadStringKey(P_ISULAT, "39.9730700");
        return ulat;
    }

    public void setUlat(String ulat) {
        this.ulat = ulat;
        writePreference(new Pair<String, Object>(P_ISULAT, this.ulat));
    }

    public String getUlng() {
        ulng = mPreference.loadStringKey(P_ISULNG, "116.5076935");
        return ulng;
    }

    public void setUlng(String ulng) {
        this.ulng = ulng;
        writePreference(new Pair<String, Object>(P_ISULNG, this.ulng));
    }

    /**
     * The singleton instance
     */
    private static Session mInstance;

    public static Session get(Context context) {

        if (mInstance == null) {
            mInstance = new Session(context);
        }
        return mInstance;
    }

    private boolean isRunning;
    private boolean isLogin;
    /**
     * 登录相关token
     */
    private String token;
    private String deviceToken;

    /**
     * 当天的日期 YY-MM-DD
     */
    private String date;

    /**
     * 角色：会员、检测机构
     */
    private Integer role;

    /**
     * 用户信息
     */
    private Member member;

    /**
     * 检测机构管理员
     */
    private SupplierAdmin suppilerAdmin;

    /**
     * 是否已经选择了个人兴趣标签
     */
    private boolean isFavorate = false;

    public boolean isFavorate() {
        isFavorate = mPreference.loadBooleanKey(P_ISFAVOR, false);
        return isFavorate;
    }

    public void setFavorate(boolean favorate) {
        if (this.isFavorate == favorate) {
            return;
        }
        this.isFavorate = favorate;
        writePreference(new Pair<String, Object>(P_ISFAVOR, isFavorate));

    }

    private boolean isDefault = false;

    public boolean isDefault() {
        isDefault = mPreference.loadBooleanKey(P_DEFAULT_SCENES, false);
        return isDefault;
    }

    public void setDefault(boolean defaults) {
        if (this.isDefault == defaults) {
            return;
        }
        this.isDefault = defaults;
        writePreference(new Pair<String, Object>(P_DEFAULT_SCENES, isDefault));

    }

    public Integer getRole() {
//        role = mPreference.loadIntKey(P_ROLE, 0);
//        return role;
        String s = ACache.get(mContext).getAsString(P_ROLE);
        return Integer.parseInt(s != null ? s : "0");
    }

    public void setRole(Integer role) {
//        if (this.role == role) {
//            return;
//        }
//        this.role = role;
//        writePreference(new Pair<String, Object>(P_ROLE, role));
        ACache.get(mContext).put(P_ROLE, "" + role);
    }

    public Member getUserInfo() {
        member = (Member) StringToObject(mPreference.loadStringKey(P_USER, ""));
        return member;
    }

    public void setUserInfo(Member member) {
        if (member == null) {
            return;
        }
        this.member = member;
        writePreference(new Pair<String, Object>(P_USER, member));
    }

    public SupplierAdmin getSuppilerAdmin() {
        suppilerAdmin = (SupplierAdmin) StringToObject(mPreference.loadStringKey(P_SUPPLIER, ""));
        return suppilerAdmin;
    }

    public void setSuppilerAdmin(SupplierAdmin suppilerAdmin) {
        if (suppilerAdmin == null) {
            return;
        }
        this.suppilerAdmin = suppilerAdmin;
        writePreference(new Pair<String, Object>(P_SUPPLIER, suppilerAdmin));
    }

    private boolean isNetImg;

    public boolean isNetImg() {
        isNetImg = mPreference.loadBooleanKey(P_ISNETIMG, false);
        return isNetImg;
    }

    public void setNetImg(boolean netImg) {
        if (this.isNetImg == netImg) {
            return;
        }
        this.isNetImg = netImg;
        writePreference(new Pair<String, Object>(P_ISNETIMG, isNetImg));
    }

    public static final String P_ISLOGIN = "pref.dujiaoshou.isLogin";
    public static final String P_ISNETIMG = "pref.dujiaoshou.isNetImg";
    public static final String P_ISUPUSH = "pref.dujiaoshou.isPush";
    public static final String P_ISFAVOR = "pref.dujiaoshou.isFavor";
    public static final String P_ISULAT = "pref.dujiaoshou.ulat";
    public static final String P_ISULNG = "pref.dujiaoshou.ulng";
    public static final String P_APP_TOKEN = "token";
    public static final String P_APP_DEVICETOKEN = "pref.dujiaoshou.deviceToken";
    public static final String P_APP_DATE = "date";
    public static final String P_ROLE = "pref.dujiaoshou.role";
    public static final String P_USER = "pref.dujiaoshou.user";
    public static final String P_SUPPLIER = "pref.dujiaoshou.supplier";
    public static final String P_DEFAULT_SCENES = "pref.dujiaoshou.isDefault";
    public static final String P_GUID = "pref.dujiaoshou.guid";
    public static final String P_IEIM = "pref.dujiaoshou.imei";


    private void readSettings() {
        isRunning = mPreference.loadBooleanKey("isRunning", false);
//        role = mPreference.loadIntKey(P_ROLE, 0);
        role = Integer.parseInt(ACache.get(mContext).getAsString(P_ROLE));
        isLogin = mPreference.loadBooleanKey(P_ISLOGIN, false);
        token = mPreference.loadStringKey(P_APP_TOKEN, null);
        date = mPreference.loadStringKey(P_APP_DATE, null);
        getApplicationInfo();
    }

    public String getDeviceToken() {
        deviceToken = mPreference.loadStringKey(P_APP_DEVICETOKEN, "");
        return deviceToken;
    }

    public void setDeviceToken(String deviceToken) {
        this.deviceToken = deviceToken;
        writePreference(new Pair<String, Object>(P_APP_DEVICETOKEN, deviceToken));
    }

    public boolean isLogin() {
        return isLogin;
    }

    public void setLogin(boolean isLogin) {
        if (this.isLogin == isLogin) {
            return;
        }
        this.isLogin = isLogin;
        writePreference(new Pair<String, Object>(P_ISLOGIN, isLogin));
    }

    /**
     * Write session value back to preference
     */
    public void writePreference(Pair<String, Object> updateItem) {

        final String key = updateItem.first;
        //需要加密保存的内容
        if (P_APP_TOKEN.equals(key)) {

            mPreference.saveStringKey(key,
                    SecurityUtil.encrypt(String.valueOf(updateItem.second)));
            //boolean保存内容
        } else if (P_ISLOGIN.equals(key) || P_ISFAVOR.equals(key)
                || P_ISUPUSH.equals(key) || P_ISNETIMG.equals(key)
                || P_DEFAULT_SCENES.equals(key)) {
            mPreference.saveBooleanKey(key, (Boolean) updateItem.second);
            //字符串保存内容
        } else if (P_APP_DATE.equals(key) || P_APP_DEVICETOKEN.equals(key)
                || P_ISULNG.equals(key) || P_ISULAT.equals(key) || P_GUID.equals(key)
                || P_IEIM.equals(key)) {
            mPreference.saveStringKey(key, (String) updateItem.second);

            //对象保存内容
        } else if (P_USER.equals(key)) {
            String string = ObjectToString(updateItem.second);
            mPreference.saveStringKey(key, string);
            //数值型保存内容
        } else if ("".equals(key)) {

            mPreference.saveIntKey(key, (Integer) updateItem.second);

        } else {
            return;
        }

    }

    /**
     * The Application version name
     */
    private String versionName;

    public String getVersionName() {
        return versionName;
    }

    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }

    /**
     * The mobile IMEI code
     */
    private String imei = "";

    /**
     * The mobile sim code
     */
    private String sim;

    /**
     * The Application Debug flag
     */
    private String debugType;

    /**
     * The Application version name
     */
    private String appName;

    /**
     * The Application Version Code
     */
    private int versionCode;

    public String getChannelId() {
        channelId = STIDUtil.getChannelId(mContext);
        return channelId;
    }

    public void setChannelId(String channelId) {
        this.channelId = channelId;
    }

    /**
     * 渠道号
     */
    private String channelId = "10000";
    /**
     * 渠道名称
     */
    private String channelName;

    /**
     * The Application package name
     */
    private String packageName;

    /**
     * The application debug mode Debug模式开启
     */
    public boolean isDebug;


    /**
     * Log tag
     */
    private final static String TAG = "Session";

    /*
    * 读取App配置信息
    */
    private void getApplicationInfo() {

        final PackageManager pm = mContext.getPackageManager();
        try {
            final PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(),
                    0);
            versionName = pi.versionName;
            versionCode = pi.versionCode;

            final ApplicationInfo ai = pm.getApplicationInfo(
                    mContext.getPackageName(), PackageManager.GET_META_DATA);

            appName = String.valueOf(ai.loadLabel(pm));
            LogUtils.appTagPrefix = appName;
            packageName = mContext.getPackageName();

            if (TextUtils.isEmpty(imei)) {
                imei = STIDUtil.getDeviceId(mContext);
                setImei(imei);
            }
            channelName = ai.metaData.get(ConstantValues.UMENG_CHANNEL).toString();
            channelId = STIDUtil.getChannelIdByChannelName(channelName);
            debugType = ai.metaData.get("app_debug").toString();

            if ("1".equals(debugType)) {
                // developer mode
                isDebug = true;
            } else if ("0".equals(debugType)) {
                // release mode
                isDebug = false;
            }
            LogUtils.allow = isDebug;
        } catch (PackageManager.NameNotFoundException e) {
            Log.d(TAG, "met some error when get application info");
        }
    }


    private String ObjectToString(Object obj) {
        String productBase64 = null;
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            productBase64 = new String(Base64.encodeBase64(baos.toByteArray()));
        } catch (Exception e) {
            Log.e("错误", "保存错误" + e.toString());
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return productBase64;
    }

    private Object StringToObject(String str) {
        Object obj = null;
        byte[] base64Bytes;
        ByteArrayInputStream bais = null;
        try {
            String productBase64 = str;
            if (null == productBase64
                    || TextUtils.isEmpty(productBase64.trim())) {
                return null;
            }

            base64Bytes = Base64.decodeBase64(productBase64.getBytes());
            bais = new ByteArrayInputStream(base64Bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            obj = ois.readObject();
            ois.close();
        } catch (Exception e) {
        } finally {
            if (bais != null) {
                try {
                    bais.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return obj;
    }

    private static final String com_common_first_start = "com.lashou.saas.first.start";     //是否是第一次启动,判断是否显示引导页

    public void setFirstStart(boolean isFirstStart) {
        SharedPreferencesUtil.putBoolean(com_common_first_start, isFirstStart);
    }

    public boolean isFirstStart() {
        return SharedPreferencesUtil.getBoolean(com_common_first_start, true);
    }

    public boolean isApkDownloading = false;

    public boolean isApkDownloading() {
        return isApkDownloading;
    }

    public void setApkDownloading(boolean isApkDownloading) {
        this.isApkDownloading = isApkDownloading;
    }

}